#define __announce \
[#para_available,true] call XNetSetJIP;\
{deleteVehicle _x} forEach [_chopper] + _crew;\
deleteMarker #d_drop_marker

#define __del \
{deleteVehicle _x} forEach [_chopper] + _crew;\
deleteMarker #d_drop_marker

#define __exit if (!alive _unit || !alive _chopper || !canMove _chopper) exitWith {[_crew,_chopper] spawn _delete_chop;_may_exit = true}
private ["_player","_side", "_crew", "_chopper", "_grp", "_spos", "_veca", "_wp", "_wp2", "_para", "_doit", "_vehicle", "_starttime", "_unit","_killHandler","_safedistcheck"];
if (!isServer) exitWith {};

_drop_type = _this select 0;
_drop_pos = _this select 1;
_player = _this select 2;
_the_chopper = "";
if (count _this > 3) then { _the_chopper = _this select 3; };
diag_log Format["(%1)[%2]: %3: %4",diag_tickTime,"createdrop.sqf","Start",_this];

_side = "";
If (!IsNil "_player") then {
	If (!IsNull _player) then {
		if (alive _player) then {
			_side = d_own_side;
			// _side = switch (str(side _player)) do {
				// case "WEST": {"WEST"};
				// case "GUER": {"GUER"};
				// case "EAST": {"EAST"};
				// case "CIV": {"CIV"};
				// default {""};
				// };
			diag_log Format["(%1)[%2]: %3: %4",diag_tickTime,"createdrop.sqf","Side player",_side];
		};	
	};
};

["d_dropansw", [0,_player]] call XNetCallEvent;

_drop_pos = [_drop_pos select 0, _drop_pos select 1, 120];

["para_available",false] call XNetSetJIP;

_end_pos = call XfGetRanPointOuterAir;
_dstart_pos = call XfGetRanPointOuterAir;

// If we have a carrier, all air support comes from there.
if (! isNil "LHD_Center") then {
	_end_pos = [position LHD_Center, 300] call XfGetRanPointCircleAir;
	_end_pos = [_end_pos select 0,_end_pos select 1,300];
	_dstart_pos = [position LHD_Center, 300] call XfGetRanPointCircleAir;
	_dstart_pos = [_dstart_pos select 0, _dstart_pos select 1,300];
};

_delete_chop = {
	private ["_crew","_chopper"];
	_crew = _this select 0;
	_chopper = _this select 1;
	["para_available",true] call XNetSetJIP;
	sleep 180 + random 100;
	__del;
};

_grp = [X_Drop_Side] call x_creategroup;
// If we didn't pass a chopper type as parameter, we set the default here.
if (_the_chopper == "") then { _the_chopper = x_drop_aircraft; };
_the_chute = switch (X_Drop_Side) do {
	case "WEST": {"ParachuteMediumWest"};
	case "GUER": {"ParachuteMediumWest"};
	case "EAST": {"ParachuteMediumEast"};
	case "CIV": {"ParachuteC"};
};

_spos = [_dstart_pos select 0, _dstart_pos select 1, (x_drop_fly_height + 300)];
_cdir = [_spos, _drop_pos] call XfDirTo;
_veca = [_spos, _cdir, _the_chopper, _grp] call XfSpawnVehicle;
_chopper = _veca select 0;
d_allunits_add set [count d_allunits_add, _chopper];
_chopper lock true;
_chopper allowDamage false;
removeAllWeapons _chopper;
_chopper setVariable ["asr_ai_sys_aiskill_exclude", true];
_chopper setVariable ["zeu_AIBypass", true];
{
	_x setVariable ["asr_ai_sys_aiskill_exclude", true];
	_x setVariable ["zeu_AIBypass", true];
	_x disableAI "TARGET";
	_x disableAI "AUTOTARGET";
	_x allowfleeing 0;
	_x setCaptive true;
} foreach crew _chopper;

// If the vehicle is destroyed for a reason or another, the players loses one Air Drop unit.
["d_drop_marker", [0,0,0],"ICON","ColorBlue",[0.5,0.5],"Air Drop Carrier",0,"Dot","",0.01] call XfCreateMarkerGlobal;
sleep 0.1;
_crew = _veca select 1;
_unit = driver _chopper;

_wp = _grp addWaypoint [_drop_pos, 0];
_wp setWaypointBehaviour "CARELESS";
_wp setWaypointSpeed "NORMAL";
_wp setwaypointtype "MOVE";

_wp2 = _grp addWaypoint [_end_pos, 0];
_wp2 setwaypointtype "MOVE";
_wp2 setWaypointBehaviour "CARELESS";
_wp2 setWaypointSpeed "NORMAL";

_chopper flyInHeight x_drop_fly_height;
_dist_to_drop = 150;
_may_exit = false;
sleep 12 + random 12;
["d_dropansw", [1,_player]] call XNetCallEvent;
_starttime = time + 400;

// We initialized this marker to invisble to avoid everyone seeing it in post 0,0,0
"d_drop_marker" setMarkerPos position _chopper;
"d_drop_marker" setMarkerAlpha 1;
while {_chopper distance _drop_pos > 1000} do {
	sleep 3.512;
	"d_drop_marker" setMarkerPos position _chopper;
	__exit;
	_unit doMove _drop_pos;
	if (time > _starttime && (_chopper distance _dstart_pos < 500)) exitWith {__announce;_may_exit = true};
};
if (_may_exit) exitWith {["d_dropansw", [3,_player]] call XNetCallEvent};
// We remove the captive status of the crew so that enemies can start shooting at the drop unit. And we add a eventhandler to reduce the available drop airplanes
_killHandler = _chopper addEventHandler ["killed", "diag_log 'Air Drop Destroyed!';_Available =(['available_drop_vehicles',0] call XNetGetJIP); If (_Available > 0) then { ['available_drop_vehicles',(_Available - 1)] call XNetSetJIP; };"];
_chopper allowDamage true;
{_x setCaptive false} forEach _crew;
// We lower the speed since air drops of heavy stuff don't happen at normal flying speeds.
_wp setWaypointSpeed "LIMITED";

["d_dropansw", [2,_player]] call XNetCallEvent;
while {_chopper distance _drop_pos > _dist_to_drop} do {
	sleep 1.012;
	"d_drop_marker" setMarkerPos position _chopper;
	__exit;
	_unit doMove _drop_pos;
};
if (_may_exit) exitWith {["d_dropansw", [(if (!alive _chopper) then {5} else {3}),_player]] call XNetCallEvent;};
_wp setWaypointSpeed "NORMAL";

_unit doMove _end_pos;

if (alive _chopper) then {
	[_the_chute,_chopper,_drop_type,_drop_pos,_player,_side] spawn {
		private ["_para","_the_chute","_chopper","_doit","_vehicle","_drop_type","_drop_posx","_player","_side"];
		_the_chute = _this select 0;
		_chopper = _this select 1;
		_drop_type = _this select 2;
		_drop_posx = _this select 3;
		_player = _this select 4;
		_side = _this select 5;
		_drop_posx = [_drop_posx select 0, _drop_posx select 1, 0];
		
		sleep 1.512;
		_vehicle = objNull;
		_is_ammo = false;
		_para = objNull;
		if (_drop_type in ["LocalBasicAmmunitionBox","LocalBasicWeaponsBox","GuerillaCacheBox","RUVehicleBox","RUOrdnanceBox","RULaunchersBox","RUSpecialWeaponsBox","RUBasicAmmunitionBox","RUBasicWeaponsBox","SpecialWeaponsBox","USVehicleBox","USOrdnanceBox","USLaunchersBox","USSpecialWeaponsBox","USBasicAmmunitionBox","USBasicWeaponsBox","Gunrack1","Gunrack2"]) then {
			_is_ammo = true;
			_para = createVehicle [_the_chute, [(getPosASL _chopper) select 0,(getPosASL _chopper) select 1,((position _chopper) select 2)-10], [], 0, "FLY"];
			_para setpos [(getPosASL _chopper) select 0,(getPosASL _chopper) select 1,((position _chopper) select 2) - 10];
		} else {
			_vehicle = createVehicle [_drop_type, [(getPosASL _chopper) select 0,(getPosASL _chopper) select 1,((position _chopper) select 2)-10], [], 0, "NONE"];
			_vehicle setpos [(getPosASL _chopper) select 0,(getPosASL _chopper) select 1,((position _chopper) select 2) - 10];
			_para = createVehicle [_the_chute, [0,0,0], [], 0, "FLY"];
			_para setPos (_vehicle modelToWorld [0,0,2]);
			_vehicle attachTo [_para,[0,0,0]];
			d_allunits_add set [count d_allunits_add, _vehicle];
		};
		
		["d_dropansw", [4,_player]] call XNetCallEvent;
		[_vehicle,_drop_posx,d_drop_radius,_drop_type,_para, _is_ammo,_side] execVM "scripts\mando_chute.sqf";
	};
};

_starttime = time + 300;

sleep 0.512;
// We wait that the drop vehicle is gone or it gets killed. We set the captive status back when the vehicle is 500m away from the drop point (to give it a chance to survive) and we remove the eventHandler which decrements the available vehicles
while {(time < _starttime && canMove _chopper && (_chopper distance _end_pos) > 400 && alive _unit)} do {
		sleep 1.101;
		"d_drop_marker" setMarkerPos position _chopper;
		if ((alive _chopper) And ((_chopper distance _drop_pos) >= 800) And (_killHandler >= 0)) then {
			_chopper removeEventHandler ["killed",_killHandler];
			_killHandler = -1;
			{_x setCaptive true} forEach _crew;
			_chopper allowdamage false;
			diag_log Format["(%1)[%2]: %3", diag_ticktime,"createdrop.sqf","The Air Drop Carrier exits the danger zone"];
		};
};
// If the vehicle got destroyed, we inform the player. So that he knows he lost a vehicle :)
if (!alive _unit) then {
	["d_dropansw", [5,_player]] call XNetCallEvent;
} else {
	["d_dropansw", [6,_player]] call XNetCallEvent;
};
_drop_pos = nil;

__announce;
